package com.springboot.web;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;

/**
 * @Author: TongRui乀
 * @Date: 2019/3/12 16:03
 * @description：
 */
@RestController
@RequestMapping("search")
@Slf4j
public class EsQueryApiContoller {

    @Autowired
    private TransportClient transportClient;

    /**
     *  查询所有
     * @param indexName
     * @param type
     * @return
     */
    @GetMapping("getAll/{indexName}/{type}")
    public String getAll(@PathVariable String indexName, @PathVariable String type){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type).setQuery(QueryBuilders.matchAllQuery()).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }

    /**
     *  全字段匹配
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByKeyword/{indexName}/{type}/{keyword}")
    public String getByKeyWord(@PathVariable String indexName,
                               @PathVariable String type,
                               @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type).setQuery(QueryBuilders.queryStringQuery(keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }

    /**
     *  指定字段通配符匹配
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByKeyWildcard/{indexName}/{type}/{keyword}")
    public String getByKeyWildcard(@PathVariable String indexName,
                                   @PathVariable String type,
                                   @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.wildcardQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }
        return sb.toString();
    }

    /**
     *  指定字段词条匹配
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByKeyTerm/{indexName}/{type}/{keyword}")
    public String getByKeyTerm(@PathVariable String indexName,
                               @PathVariable String type,
                               @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.termQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }

    /**
     *  支持多个关键字查询 满足任何一个即可
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByTerms/{indexName}/{type}/{keyword}")
    public String getByTerms(@PathVariable String indexName,
                             @PathVariable String type,
                             @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.termsQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }
        return sb.toString();
    }


    /**
     *  区间查询
     * @param indexName
     * @param type
     * @param from
     * @param to
     * @return
     */
    @GetMapping("getByRange/{indexName}/{type}/{from}/{to}")
    public String getByRange(@PathVariable String indexName,
                             @PathVariable String type,
                             @PathVariable String from,
                             @PathVariable String to){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.rangeQuery("score").from(from).to(to)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }


    /**
     *  指定字段模糊查询
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByKeyfuzzy/{indexName}/{type}/{keyword}")
    public String getByKeyfuzzy(@PathVariable String indexName,
                                @PathVariable String type,
                                @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.fuzzyQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }

    /**
     *  指定字段是否包含null字段
     * @param indexName
     * @param type
     * @return
     */
    @GetMapping("getExists/{indexName}/{type}/")
    public String getExists(@PathVariable String indexName,
                                @PathVariable String type){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.existsQuery("name")).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }


    /**
     *  指定字段前缀匹配查询
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getByPrefix/{indexName}/{type}/{keyword}")
    public String getByPrefix(@PathVariable String indexName,
                                @PathVariable String type,
                                @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.prefixQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }


    /**
     *  正则表达式匹配查询
     * @param indexName
     * @param type
     * @param keyword
     * @return
     */
    @GetMapping("getRegex/{indexName}/{type}/{keyword}")
    public String getRegex(@PathVariable String indexName,
                              @PathVariable String type,
                              @PathVariable String keyword){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.regexpQuery("name", keyword)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }

        return sb.toString();
    }

    /**
     *  type类型查询
     * @param indexName
     * @param type
     * @return
     */
    @GetMapping("getType/{indexName}/{type}")
    public String getType(@PathVariable String indexName,
                           @PathVariable String type){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.typeQuery(type)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }
        return sb.toString();
    }

    /**
     *  ids 查询
     * @param indexName
     * @param type
     * @return
     */
    @GetMapping("getIds/{indexName}/{type}/{ids}")
    public String getIds(@PathVariable String indexName,
                         @PathVariable String type,
                         @PathVariable String ids){

        SearchResponse searchResponse = this.transportClient.prepareSearch(indexName).setTypes(type)
                .setQuery(QueryBuilders.idsQuery().addIds(ids)).get();

        SearchHits hits = searchResponse.getHits();

        Iterator<SearchHit> iterator = hits.iterator();

        StringBuilder sb = new StringBuilder();

        while (iterator.hasNext()){

            SearchHit next = iterator.next();
            sb.append("id:").append( next.getId()).append(" ").append(next.getSourceAsString()).append("\n");
        }
        return sb.toString();
    }

}
